/* Web_Authentication.ino - Webduino Authentication example */

/* This example assumes that you're familiar with the basics
 * of the Ethernet library (particularly with setting MAC and
 * IP addresses) and with the basics of Webduino. If you
 * haven't had a look at the HelloWorld example you should
 * probably check it out first */

/* you can change the authentication realm by defining
 * WEBDUINO_AUTH_REALM before including WebServer.h */
#define WEBDUINO_AUTH_REALM "Weduino Authentication Example"

#include "SPI.h"
#include "Ethernet.h"
#include "WebServer.h"
#include "X10Firecracker.h"

#define RTS_PIN     2                   // RTS line for C17A - DB9 pin 7
#define DTR_PIN     3                   // DTR line for C17A - DB9 pin 4
#define BIT_DELAY   1                   // mS delay between bits (1 mS OK)

/* CHANGE THIS TO YOUR OWN UNIQUE VALUE.  The MAC number should be
 * different from any other devices on your network or you'll have
 * problems receiving packets. */
static uint8_t mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

/* CHANGE THIS TO MATCH YOUR HOST NETWORK.  Most home networks are in
 * the 192.168.0.XXX or 192.168.1.XXX subrange.  Pick an address
 * that's not in use and isn't going to be automatically allocated by
 * DHCP from your router. */
static uint8_t ip[] = { 192, 168, 1, 210 };

/* This creates an instance of the webserver.  By specifying a prefix
 * of "", all pages will be at the root of the server. */
#define PREFIX ""
P(htmlhead_message) =   "<html><head>"
                        "<title>ArduinoX10</title>"
                        "<meta name=\"viewport\" content=\"width=device-width; initial-scale=1.0; maximum-scale=1.0;\">"
                        "<meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />"
                        "<style>"
                          "body { font-size: 1em; } "
                          ".x10form { text-align: center; }"
                          ".x10form form select { width: 50%; font-size: 1em; }"
                          ".x10form form input { width: 90%; font-size: 1em; }"
                        "</style>"
                        "<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>"
                        "<script>"
                          "$(document).ready(function(){ $('.x10form :submit').click(function(e){e.preventDefault(); $.post('./',$(this).parent('form').serialize() + '&c='+ $(this).attr('value')); })});"
                        "</script>"
                        "</head><body>";

P(formheader_msg) =       "<div class=\"x10form\"><form method=\"post\">";
P(housecodeselect_msg) =  "<span class=\"graytitle\">House Code:</span><br>"
                          "<select name=\"hc\">"
                            "<option value=\"a\">A</option>"
                            "<option value=\"b\">B</option>"
                            "<option value=\"c\">C</option>"
                            "<option value=\"d\">D</option>"
                            "<option value=\"e\">E</option>"
                            "<option value=\"f\">F</option>"
                            "<option value=\"g\">G</option>"
                            "<option value=\"h\">H</option>"
                            "<option value=\"i\">I</option>"
                            "<option value=\"j\">J</option>"
                            "<option value=\"k\">K</option>"
                            "<option value=\"l\">L</option>"
                            "<option value=\"m\">M</option>"
                            "<option value=\"n\">N</option>"
                            "<option value=\"o\">O</option>"
                            "<option value=\"p\">P</option>"
                          "</select><br>";
P(unitselect_msg) =       "<span class=\"graytitle\">Device Code:</span><br>"
                          "<select name=\"u\">"
                            "<option value=\"1\">1</option>"
                            "<option value=\"2\">2</option>"
                            "<option value=\"3\">3</option>"
                            "<option value=\"4\">4</option>"
                            "<option value=\"5\">5</option>"
                            "<option value=\"6\">6</option>"
                            "<option value=\"7\">7</option>"
                            "<option value=\"8\">8</option>"
                            "<option value=\"9\">9</option>"
                            "<option value=\"10\">10</option>"
                            "<option value=\"11\">11</option>"
                            "<option value=\"12\">12</option>"
                            "<option value=\"13\">13</option>"
                            "<option value=\"14\">14</option>"
                            "<option value=\"15\">15</option>"
                            "<option value=\"16\">16</option>"
                          "</select><br>";
P(formfooter_msg) =       "<input type=\"submit\" name=\"c\" value=\"on\"><br>"
                          "<input type=\"submit\" name=\"c\" value=\"off\"><br>"
                          "<input type=\"submit\" name=\"c\" value=\"dim\"><br>"
                          "<input type=\"submit\" name=\"c\" value=\"bright\"></form></div>";
                        

                        


P(htmlfooter_message) = "</body></html>";
WebServer webserver(PREFIX, 80);

void privateCmd(WebServer &server, WebServer::ConnectionType type, char *, bool)
{
  /* if the user has requested this page using the following credentials
   * username = user
   * password = user
   * display a page saying "Hello User"
   *
   * the credentials have to be concatenated with a colon like
   * username:password
   * and encoded using Base64 - this should be done outside of your Arduino
   * to be easy on your resources
   *
   * in other words: "dXNlcjp1c2Vy" is the Base64 representation of "user:user"
   *
   * if you need to change the username/password dynamically please search
   * the web for a Base64 library */
  if (server.checkCredentials("dXNlcjp1c2Vy"))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello User</h1>";
      server.printP(helloMsg);
    }
  }
  /* if the user has requested this page using the following credentials
   * username = admin
   * password = admin
   * display a page saying "Hello Admin"
   *
   * in other words: "YWRtaW46YWRtaW4=" is the Base64 representation of "admin:admin" */
  else if (server.checkCredentials("YWRtaW46YWRtaW4="))
  {
    server.httpSuccess();
    if (type != WebServer::HEAD)
    {
      P(helloMsg) = "<h1>Hello Admin</h1>";
      server.printP(helloMsg);
    }
  }
  else
  {
    /* send a 401 error back causing the web browser to prompt the user for credentials */
    server.httpUnauthorized();
  }
}

#define NAMELEN 32
#define VALUELEN 32

void x10Cmd(WebServer &server, WebServer::ConnectionType type, char *url_tail, bool tail_complete)
{
  URLPARAM_RESULT rc;
  char name[NAMELEN];
  int  name_len;
  char value[VALUELEN];
  int value_len;
  
  CommandCode commandcode;
  HouseCode housecode;
  int unitcode;
  char requesttype[VALUELEN];
  boolean ccsuccess = false;
  boolean hcsuccess = false;
  boolean ucsuccess = false;
  
  
  server.httpSuccess();
  if (type == WebServer::HEAD)
    return;
  
  server.printP(htmlhead_message);
  server.printP(formheader_msg);
  server.printP(housecodeselect_msg);
  server.printP(unitselect_msg);
  server.printP(formfooter_msg);
  server.printP(htmlfooter_message);

  //get the request type
  
  if (strlen(url_tail))
  {
    while (strlen(url_tail))
    {
      rc = server.nextURLparam(&url_tail, name, NAMELEN, value, VALUELEN);
      if (rc != URLPARAM_EOS)
      {
        if(strcmp(name,"c") == 0) { //commandtype
          commandcode = parseCommandType(value,&ccsuccess);
        }
        if(strcmp(name,"hc") == 0) { //HOUSECODE
          housecode = parseHouseCode(value,&hcsuccess);
        }
        if(strcmp(name,"u") == 0) { //unitcode
          unitcode = atoi(value);
          if(unitcode <= 16 && unitcode >= 1)
            ucsuccess = true;
        }
      }
    }
  }
  if (type == WebServer::POST)
  {
    while (server.readPOSTparam(name, NAMELEN, value, VALUELEN))
    {
        if(strcmp(name,"c") == 0) { //commandtype
          commandcode = parseCommandType(value,&ccsuccess);
        }
        if(strcmp(name,"hc") == 0) { //HOUSECODE
          housecode = parseHouseCode(value,&hcsuccess);
        }
        if(strcmp(name,"u") == 0) { //unitcode
          unitcode = atoi(value);
          if(unitcode <= 16 && unitcode >= 1)
            ucsuccess = true;
        }
    }
  }
  
  if(ccsuccess && hcsuccess && ucsuccess)
  {
    X10.sendCmd( housecode, unitcode, commandcode );
  }

}

CommandCode parseCommandType(char * value, boolean * success)
{
  CommandCode code;
  if(strcmp(value,"on") == 0) { code = cmdOn; *success = true; }
  if(strcmp(value,"off") == 0) { code = cmdOff; *success = true; }
  if(strcmp(value,"dim") == 0) { code = cmdDim; *success = true; }
  if(strcmp(value,"bright") == 0) { code = cmdBright; *success = true; }
  return code;
}

HouseCode parseHouseCode(char * value, boolean * success)
{
  HouseCode code;
  if(strcmp(value,"a") == 0) { code = hcA; *success = true; }
  if(strcmp(value,"b") == 0) { code = hcB; *success = true; }
  if(strcmp(value,"c") == 0) { code = hcC; *success = true; }
  if(strcmp(value,"d") == 0) { code = hcD; *success = true; }
  if(strcmp(value,"e") == 0) { code = hcE; *success = true; }
  if(strcmp(value,"f") == 0) { code = hcF; *success = true; }
  if(strcmp(value,"g") == 0) { code = hcG; *success = true; }
  if(strcmp(value,"h") == 0) { code = hcH; *success = true; }
  if(strcmp(value,"i") == 0) { code = hcI; *success = true; }
  if(strcmp(value,"j") == 0) { code = hcJ; *success = true; }
  if(strcmp(value,"k") == 0) { code = hcK; *success = true; }
  if(strcmp(value,"l") == 0) { code = hcL; *success = true; }
  if(strcmp(value,"m") == 0) { code = hcM; *success = true; }
  if(strcmp(value,"n") == 0) { code = hcN; *success = true; }
  if(strcmp(value,"o") == 0) { code = hcO; *success = true; }
  if(strcmp(value,"p") == 0) { code = hcP; *success = true; }
  return code;
}

void setup()
{
  X10.init(RTS_PIN, DTR_PIN, BIT_DELAY);
  Ethernet.begin(mac, ip);
  webserver.setDefaultCommand(&x10Cmd);
  webserver.begin();
}

void loop()
{
  char buff[64];
  int len = 64;

  /* process incoming connections one at a time forever */
  webserver.processConnection(buff, &len);
}
